Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow apc_modbus instances to monitor several USB devices on the same system #2790

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

jimklimov
Copy link
Member

@jimklimov jimklimov commented Jan 29, 2025

As part of discussion at #2609 an issue was identified, where the driver did not ignore devices actively rejected by a matcher (e.g. one with a different serial number string), and so two drivers tried to manage the same device.

This probably does not solve the main problems of that ticket, but at least gets us one problem less...

Another change is about trying to clean out reopen_matcher if we need to free it during reconnection. Original code seemed to assume it was the first one in stack, new code tries to walk the list of known matchers and actually check for it before freeing, and drop the linked list entry.

This also brings in the familiar NUT printout of USB device details, e.g. (matching the FTDI Serial-USB chip below, for the lack of actual APC UPS here, with an extra char in Serial field):

:; sudo ./drivers/apc_modbus -DDDDDDDD -s tempups -d1 -x port=auto -x vendorid=0403 -x productid=6001 -x serial=FTFV43590 -u root
   0.000001     [D5] send_to_all: SETINFO driver.state "init.starting"
Network UPS Tools 2.8.2.2026.3-2029-g22b2d5cf0 (development iteration after 2.8.2) - NUT APC Modbus driver with USB support 0.11
   0.000411     [D5] send_to_all: SETINFO driver.version.usb "libusb-1.0.26 (API: 0x01000109)"
   0.000444     [D1] Using USB implementation: libusb-1.0.26 (API: 0x01000109)
   0.000483     [D1] This build of the driver is USB-capable; also Serial and TCP Modbus RTU are supported
   0.000540     [D3] main_arg: var='port' val='auto'
   0.000572     [D6] testinfo_reloadable: var=port, infoname=driver.parameter.port, newval=auto, reloadable=0, reload_flag=0
   0.000610     [D6] testinfo_reloadable: verdict for (re)loading var=port value: 1
   0.000651     [D5] send_to_all: SETINFO driver.parameter.port "auto"
   0.000679     [D3] main_arg: var='vendorid' val='0403'
   0.000721     [D5] send_to_all: SETINFO driver.parameter.vendorid "0403"
   0.000749     [D3] main_arg: var='productid' val='6001'
   0.000782     [D5] send_to_all: SETINFO driver.parameter.productid "6001"
   0.000816     [D3] main_arg: var='serial' val='FTFV43590'
   0.000850     [D5] send_to_all: SETINFO driver.parameter.serial "FTFV43590"
   0.000877     [D1] Built-in default or configured user for drivers 'nobody' was ignored due to 'root' specified on command line
   0.000899     [D1] Network UPS Tools version 2.8.2.2026.3-2029-g22b2d5cf0 (development iteration after 2.8.2) built with gcc (Debian 12.2.0-14) 12.2.0 and configured with flags: --prefix=/home/jim/nut/tmp --with-all=auto --without-docs --with-modbus+usb
   0.000934     [D1] debug level is '8'
   0.000963     [D5] send_to_all: SETINFO driver.debug "8"
   0.000993     [D5] send_to_all: SETFLAGS driver.debug RW NUMBER
   0.001909     [D1] Succeeded to become_user(root): now UID=0 GID=0
   0.001970     [D1] Signalling UPS [tempups]: driver.exit (quietly, no fuss if no driver is running or responding)
   0.002035     Can't open /var/state/ups/apc_modbus-tempups: No such file or directory
   0.002176     [D1] Request for other driver to exit returned code -1
   0.002344     [D1] Socket dialog with the other driver instance (may be absent) failed: No such file or directory
   0.002486     [D5] send_to_all: SETINFO device.type "ups"
   0.002682     [D5] send_to_all: SETINFO driver.state "init.device"
Number of USB devices: 4
Considering device #0 (0403:6001)
_modbus_rtu_usb_connect: failed to get HID descriptor: Input/Output Error
   0.041990     [D2] - VendorID: 0403
   0.042323     [D2] - ProductID: 6001
   0.042553     [D2] - Manufacturer: FTDI
   0.042746     [D2] - Product: TTL232R-3V3
   0.042782     [D2] - Serial Number: FTFV4359
   0.042815     [D2] - Bus: 001
   0.042840     [D2] - Bus Port: 003
   0.042863     [D2] - Device: 004
   0.042887     [D2] - Device release number: 0600
   0.042945     [D2] Trying to match device
   0.042971     [D5] _apc_modbus_usb_callback: current_matcher=0x55b80fa200
   0.042998     [D3] match_function_regex: matching a device...
   0.043371     [D2] match_function_regex: failed match of Serial: FTFV4359
   0.043518     [D5] _apc_modbus_usb_callback: Tried matcher 0x55b80fa200 returned 0
   0.043785     [D2] _apc_modbus_usb_callback: Device does not match - skipping
Considering device #1 (0424:ec00)
_modbus_rtu_usb_connect: failed to get HID descriptor: Input/Output Error
   0.045177     [D2] - VendorID: 0424
   0.045640     [D2] - ProductID: ec00
   0.045840     [D2] - Manufacturer: unknown
   0.045868     [D2] - Product: unknown
   0.045893     [D2] - Serial Number: unknown
   0.045916     [D2] - Bus: 001
   0.045939     [D2] - Bus Port: 001
   0.045962     [D2] - Device: 003
   0.045987     [D2] - Device release number: 0200
   0.046009     [D2] Trying to match device
   0.046035     [D5] _apc_modbus_usb_callback: current_matcher=0x55b80fa200
   0.046272     [D3] match_function_regex: matching a device...
   0.046428     [D2] match_function_regex: failed match of VendorID:  424
   0.046580     [D5] _apc_modbus_usb_callback: Tried matcher 0x55b80fa200 returned 0
   0.046610     [D2] _apc_modbus_usb_callback: Device does not match - skipping
Considering device #2 (0424:9514)
_modbus_rtu_usb_connect: failed to get HID descriptor: Input/Output Error
   0.047862     [D2] - VendorID: 0424
   0.047944     [D2] - ProductID: 9514
   0.048409     [D2] - Manufacturer: unknown
   0.048629     [D2] - Product: unknown
   0.048697     [D2] - Serial Number: unknown
   0.048743     [D2] - Bus: 001
   0.048767     [D2] - Bus Port: 001
   0.048790     [D2] - Device: 002
   0.049068     [D2] - Device release number: 0200
   0.049242     [D2] Trying to match device
   0.049376     [D5] _apc_modbus_usb_callback: current_matcher=0x55b80fa200
   0.049508     [D3] match_function_regex: matching a device...
   0.049691     [D2] match_function_regex: failed match of VendorID:  424
   0.049788     [D5] _apc_modbus_usb_callback: Tried matcher 0x55b80fa200 returned 0
   0.049817     [D2] _apc_modbus_usb_callback: Device does not match - skipping
No matching device found
   0.050664     modbus_connect: unable to connect: No such device
   0.050777     [D5] send_to_all: SETINFO driver.state "cleanup.exit"

Similar match for the correct serial (fails later as a not-modbus device, but that is beside the point):

:; sudo ./drivers/apc_modbus -DDDDDDDD -s tempups -d1 -x port=auto -x vendorid=0403 -x productid=6001 -x serial=FTFV4359 -u root
   0.000001     [D5] send_to_all: SETINFO driver.state "init.starting"
Network UPS Tools 2.8.2.2026.3-2029-g22b2d5cf0 (development iteration after 2.8.2) - NUT APC Modbus driver with USB support 0.11
   0.000511     [D5] send_to_all: SETINFO driver.version.usb "libusb-1.0.26 (API: 0x01000109)"
   0.000547     [D1] Using USB implementation: libusb-1.0.26 (API: 0x01000109)
   0.000573     [D1] This build of the driver is USB-capable; also Serial and TCP Modbus RTU are supported
   0.000638     [D3] main_arg: var='port' val='auto'
   0.000671     [D6] testinfo_reloadable: var=port, infoname=driver.parameter.port, newval=auto, reloadable=0, reload_flag=0
   0.000711     [D6] testinfo_reloadable: verdict for (re)loading var=port value: 1
   0.000744     [D5] send_to_all: SETINFO driver.parameter.port "auto"
   0.000771     [D3] main_arg: var='vendorid' val='0403'
   0.000814     [D5] send_to_all: SETINFO driver.parameter.vendorid "0403"
   0.000841     [D3] main_arg: var='productid' val='6001'
   0.000882     [D5] send_to_all: SETINFO driver.parameter.productid "6001"
   0.000912     [D3] main_arg: var='serial' val='FTFV4359'
   0.000946     [D5] send_to_all: SETINFO driver.parameter.serial "FTFV4359"
   0.000972     [D1] Built-in default or configured user for drivers 'nobody' was ignored due to 'root' specified on command line
   0.000994     [D1] Network UPS Tools version 2.8.2.2026.3-2029-g22b2d5cf0 (development iteration after 2.8.2) built with gcc (Debian 12.2.0-14) 12.2.0 and configured with flags: --prefix=/home/jim/nut/tmp --with-all=auto --without-docs --with-modbus+usb
   0.001048     [D1] debug level is '8'
   0.001079     [D5] send_to_all: SETINFO driver.debug "8"
   0.001108     [D5] send_to_all: SETFLAGS driver.debug RW NUMBER
   0.002047     [D1] Succeeded to become_user(root): now UID=0 GID=0
   0.002108     [D1] Signalling UPS [tempups]: driver.exit (quietly, no fuss if no driver is running or responding)
   0.003469     Can't open /var/state/ups/apc_modbus-tempups: No such file or directory
   0.003664     [D1] Request for other driver to exit returned code -1
   0.003818     [D1] Socket dialog with the other driver instance (may be absent) failed: No such file or directory
   0.003969     [D5] send_to_all: SETINFO device.type "ups"
   0.004102     [D5] send_to_all: SETINFO driver.state "init.device"
Number of USB devices: 4
Considering device #0 (0403:6001)
_modbus_rtu_usb_connect: failed to get HID descriptor: Input/Output Error
   0.046332     [D2] - VendorID: 0403
   0.046503     [D2] - ProductID: 6001
   0.046647     [D2] - Manufacturer: FTDI
   0.046776     [D2] - Product: TTL232R-3V3
   0.046970     [D2] - Serial Number: FTFV4359
   0.047112     [D2] - Bus: 001
   0.047236     [D2] - Bus Port: 003
   0.047364     [D2] - Device: 004
   0.047495     [D2] - Device release number: 0600
   0.047689     [D2] Trying to match device
   0.047865     [D5] _apc_modbus_usb_callback: current_matcher=0x557c1b7200
   0.047997     [D3] match_function_regex: matching a device...
   0.048408     [D5] _apc_modbus_usb_callback: Tried matcher 0x557c1b7200 returned 1
   0.048573     [D2] _apc_modbus_usb_callback: Matched FTDI TTL232R-3V3 (USB VID/PID 0403:6001)
   0.048700     _apc_modbus_usb_callback: No HID report descriptor, using defaults
   0.048840     [D5] send_to_all: SETINFO ups.vendorid "0403"
   0.048989     [D5] send_to_all: SETINFO ups.productid "6001"
Found Device 0 (Path 1-1.3):
  Vendor ID: 0x0403
  Product ID: 0x6001
Got a list of 3 libusb file descriptors to poll
   0.049552     [D5] send_to_all: SETINFO driver.state "init.quiet"
   0.049717     [D5] send_to_all: SETINFO driver.version "2.8.2.2026.3-2029-g22b2d5cf0"
   0.049859     [D5] send_to_all: SETINFO driver.version.internal "0.11"
   0.050009     [D5] send_to_all: SETINFO driver.name "apc_modbus"
   0.050183     [D5] send_to_all: SETINFO driver.state "init.info"
[01][03][02][04][00][78]
Waiting for a confirmation...
_modbus_receive_msg: context->socket=-1
Using a backend without a file descriptor, will not natively select() on it.
(5) Input/output error
ERROR Input/output error: ctx->backend->select
   0.051019     _apc_modbus_read_registers: Read of 516:636 failed: Input/output error (auto)
   0.051157     _apc_modbus_handle_error: Closing connection
   0.052183     Can't read inventory information from the UPS
   0.052418     [D5] send_to_all: SETINFO driver.state "cleanup.upsdrv"
   0.052581     [D5] send_to_all: SETINFO driver.state "cleanup.exit"

It should also fix the _apc_modbus_usb_callback: Failed to match!: Success reports :)

:; ./drivers/apc_modbus -DDDDDDDD -s tempups -d1 -x port=/dev/ttyUSB0
   0.000000     [D5] send_to_all: SETINFO driver.state "init.starting"
Network UPS Tools 2.8.2.2020-2020-g81954ea92 (development iteration after 2.8.2) - NUT APC Modbus driver with USB support 0.11
   0.000879     [D5] send_to_all: SETINFO driver.version.usb "libusb-1.0.26 (API: 0x01000109)"
   0.001103     [D1] Using USB implementation: libusb-1.0.26 (API: 0x01000109)
   0.001271     [D1] This build of the driver is USB-capable; also Serial and TCP Modbus RTU are supported
   0.001441     [D3] main_arg: var='port' val='/dev/ttyUSB0'
   0.001555     [D6] testinfo_reloadable: var=port, infoname=driver.parameter.port, newval=/dev/ttyUSB0, reloadable=0, reload_flag=0
   0.001599     [D6] testinfo_reloadable: verdict for (re)loading var=port value: 1
   0.001637     [D5] send_to_all: SETINFO driver.parameter.port "/dev/ttyUSB0"
   0.001659     [D1] Network UPS Tools version 2.8.2.2020-2020-g81954ea92 (development iteration after 2.8.2) built with gcc (Debian 12.2.0-14) 12.2.0 and configured with flags: --prefix=/home/jim/nut/tmp --with-all=auto --without-docs --with-modbus+usb
   0.001738     [D1] debug level is '8'
   0.001772     [D5] send_to_all: SETINFO driver.debug "8"
   0.001804     [D5] send_to_all: SETFLAGS driver.debug RW NUMBER
   0.002544     [D1] Can not become_user(nobody): not root initially, remaining UID=1000 GID=1000
   0.002685     Can't chdir to /var/state/ups (but we do not require that to dump data): Permission denied
   0.002858     [D1] Signalling UPS [tempups]: driver.exit (quietly, no fuss if no driver is running or responding)
   0.003013     Can't open /var/state/ups/apc_modbus-tempups: Permission denied
   0.003152     [D1] Request for other driver to exit returned code -1
   0.003281     [D1] Socket dialog with the other driver instance (may be absent) failed: Permission denied
   0.003424     [D5] send_to_all: SETINFO device.type "ups"
   0.003587     [D5] send_to_all: SETINFO driver.state "init.device"
   0.003740     WARNING: warn_if_bad_usb_port_filename(): port argument specified to
  the driver is "/dev/ttyUSB0" but USB drivers do not use it and rely on
  libusb walking all devices and matching their identification metadata.
  NUT documentation recommends port="auto" for USB devices to avoid confusion.
Number of USB devices: 4
Considering device #0 (0403:6001)
_modbus_rtu_usb_connect: failed to get HID descriptor: Input/Output Error
   0.052485     [D1] _apc_modbus_usb_callback: Failed to match!: Success
Considering device #1 (0424:ec00)
libusb_open for device #1 failed: Access denied (insufficient permissions)
Considering device #2 (0424:9514)
libusb_open for device #2 failed: Access denied (insufficient permissions)
No matching device found
   0.054362     modbus_connect: unable to connect: No such device
   0.054454     [D5] send_to_all: SETINFO driver.state "cleanup.exit"

…the freed reopen_matcher does not remain in the chain from best_matcher upwards [networkupstools#2609]

Signed-off-by: Jim Klimov <[email protected]>
…from current_matcher->match_function() [networkupstools#2609]

Signed-off-by: Jim Klimov <[email protected]>
…ommon return codes from matcher methods, like libusb1.c does [networkupstools#2609]

Notably, handle active rejection of a candidate device by the matcher
properly - go try the next device!

Signed-off-by: Jim Klimov <[email protected]>
@jimklimov jimklimov added APC USB modbus USB-duplicate-devices Track bugs and issues about monitoring several devices that seem identical to NUT or libusb impacts-release-2.8.2 Issues reported against NUT release 2.8.2 (maybe vanilla or with minor packaging tweaks) labels Jan 29, 2025
@jimklimov jimklimov added this to the 2.8.3 milestone Jan 29, 2025
@jimklimov jimklimov added the need testing Code looks reasonable, but the feature would better be tested against hardware or OSes label Jan 29, 2025
…atcher in the list is the old reopen_matcher(), rely on _apc_modbus_create_reopen_matcher() to do the right job [networkupstools#2609]

Signed-off-by: Jim Klimov <[email protected]>
@jimklimov
Copy link
Member Author

jimklimov commented Feb 5, 2025

Will convert to draft for now, according to reports in #2609 some of these changes may be wrong; at least the driver seems to lock up and time out in initial data collection from an actual UPS. Maybe I've got the "matcher" list manipulation wrong, will need to review again.

@jimklimov jimklimov marked this pull request as draft February 5, 2025 08:10
@AppVeyorBot
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
APC impacts-release-2.8.2 Issues reported against NUT release 2.8.2 (maybe vanilla or with minor packaging tweaks) modbus need testing Code looks reasonable, but the feature would better be tested against hardware or OSes USB USB-duplicate-devices Track bugs and issues about monitoring several devices that seem identical to NUT or libusb
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants